#ifndef INC_MAINWINDOW_H
#define INC_MAINWINDOW_H

#include "../base/Observer.h"
#include "controller/DiagramMan.h"
#include "controller/ToolMan.h"
#include "controller/ModifyTextCmd.h"

#include <memory>
#include <QMainWindow>

class UMLObject;
class QTextEdit;

class MainWindow : public QMainWindow
{
	Q_OBJECT;

	public:
		MainWindow(QWidget *parent = NULL);

	public slots:
		void newDiagram();
		void openDiagram();
		void saveDiagram();
		void saveDiagramAs();

	private slots:
		void onActiveChanged(DiagramFam* fam);
		void edit(UMLObject*);
		void onTextChanged();
		void focusChanged(QWidget*, QWidget*);
		void undo();
		void redo();

	private:
		QAction* _undo; // init-checked
		QAction* _redo; // init-checked
		QTextEdit* _textEdit; // init-checked

		DiagramMan _dman;

		// Declared after DiagramMan: satisfies destruction order req.
		ToolMan _tman;

		// UMLObject to edit is stored in here
		std::auto_ptr<ModifyTextCmd> _modifyTextCmd;

		class AcceptorObs : public Observer
		{
			public:
				/**
				 * Context will only be stored. Only update() dereferences it.
				 */
				AcceptorObs(MainWindow *context);

				void update(Observable*);

			private:
				MainWindow* _context;
		} _acceptorObs;

		void createMenus();
		void createPalette();
		void createTextEdit();
		void select(UMLObject* object);

		/**
		 * Sends a pending _modifyTextCmd if there is one.
		 */
		void sendModifyTextCmd();

		/**
		 * Refreshes enabled/disabled state of undo and redo actions. Properly
		 * handles absence of active diagram.
		 */
		void refreshUndoRedo();
};

#endif

